`
https://leetcode.cn/problems/3sum-closest/
`

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var threeSumClosest = function (nums, target) {
  nums.sort((a, b) => a - b)
  const n = nums.length
  let bestTarget = Infinity

  // 枚举 a
  for (let i = 0; i < n; i++) {
    // 重复的不用枚举
    if (i > 0 && nums[i] === nums[i - 1]) {
      continue
    }
    // 双指针枚举 b 和 c
    let j = i + 1, k = n - 1
    while (j < k) {
      const sum = nums[i] + nums[j] + nums[k]
      // 直接返回答案
      if (sum === target) return target
      // 根据绝对差值更新答案
      if (Math.abs(sum - target) < Math.abs(target - bestTarget)) {
        bestTarget = sum
      }
      if (sum > target) {
        // 如果和大于 target，移动 c 对应的指针
        let k0 = k - 1;
        // 移动到下一个不相等的元素
        while (j < k0 && nums[k0] == nums[k]) {
          --k0;
        }
        k = k0;
      } else {
        // 如果和小于 target，移动 b 对应的指针
        let j0 = j + 1;
        // 移动到下一个不相等的元素
        while (j0 < k && nums[j0] == nums[j]) {
          ++j0;
        }
        j = j0;
      }
    }
  }
  return bestTarget
};